import 'dart:async';

import 'package:star_author/env/env_config.dart';
import 'package:star_author/route/route_util.dart';
import 'package:star_author/utils/common_util/log_util.dart';
import 'package:star_author/utils/common_util/toast/custom_toast.dart';
import 'package:star_author/utils/rong_im/rong_im.dart';
import 'package:star_author/utils/user_util.dart';
import 'package:star_author/views/login/login_page.dart';
import 'package:star_author/views/login/phone_login.dart';
import 'package:dio/dio.dart';
import 'package:dio_log/interceptor/dio_log_interceptor.dart';
import 'package:fk_user_agent/fk_user_agent.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_navigation/src/extension_navigation.dart';

import '../../event_bus/global_event_bus.dart';
import '../../event_bus/user_login_event.dart';
import '../../views/stream/overlay_video.dart';
import 'api_manager.dart';

class HttpUtil {
  static const String MethodGet = "GET";
  static const String MethodPost = "POST";
  static const String MethodPut = "PUT";
  static const String MethodDelete = "DELETE";

  static String getServerPath() {
    String url = '';
    switch (EnvConfig.instance!.env) {
      case Env.DEV:
        url = ApiManager.DevUrl;
        break;
      case Env.TEST:
        url = ApiManager.TestUrl;
        break;
      case Env.PROD:
        url = ApiManager.ProdUrl;
        break;
    }
    return url;
  }

  static getRequestParams(
    BaseOptions options, {
    required String url,
    required String method,
    Map<String, dynamic>? queryParameters,
    dynamic data,
  }) {
    String version = "1.13";

    options.headers['X-Authorization'] = UserUtil.getToken(Get.context!);
    options.headers['X-APP-VERSION'] = version;
    options.headers['X-ORIGINAL-UA'] = FkUserAgent.webViewUserAgent ?? '';

    ///加密签名
    // String signatureString = HttpCryptUtil.createSignString(
    //   url: url,
    //   method: method,
    //   queryParameters: queryParameters,
    //   data: data,
    // );
    // options.headers['X-Signature'] = signatureString;
  }

  static dioErrorHandle(BuildContext context, dynamic error, bool isErrorToast,
      {bool isCatchErrorLogin = true}) {
    LogUtil.e('error:$error');
    if (isErrorToast) {
      EasyLoading.dismiss();
      if (error is DioError) {
        if (CancelToken.isCancel(error)) {
          LogUtil.v('request is cancel');
        } else if (error.response?.data != null &&
            error.response?.data["msg"] != null) {
          CustomToast.showImportant("${error.response?.data["msg"] ?? ""}");
        } else if (error.response?.statusCode == 500) {
          CustomToast.showImportant("当前无法连接正常，请联系客服");
        } else if (error.type == DioErrorType.connectTimeout ||
            error.type == DioErrorType.receiveTimeout ||
            error.type == DioErrorType.sendTimeout) {
          CustomToast.showImportant('连接超时，请检查网络！');
        } else if (error.type == DioErrorType.response) {
          CustomToast.showImportant('服务器异常，请稍候再试！');
        } else {
          CustomToast.showImportant("请求出错，请稍候再试！");
        }
      } else {
        CustomToast.showImportant("请求出错，请稍候再试！");
      }
    }

    if (error is DioError) {
      ///签名失效，重新请求
      if (error.response?.statusCode == 403) {
        // HttpCryptUtil.requestCrypt();
      }

      // 需要重新登录
      if (error.response?.statusCode == 401 &&
          !UserUtil.tokenIsInvalid &&
          isCatchErrorLogin) {
        CustomToast.showImportant(error.response?.data["msg"] ?? "");
        OverlayVideo.hidden();
        UserUtil.tokenIsInvalid = false;

        if (UserUtil.isLogin(context)) {
          UserUtil.onLogout(context);
        }

        //当前页面是登陆页面时候 不在跳转
        String routeSettingName = Get.currentRoute;
        if (routeSettingName == LoginPage.routeName ||
            routeSettingName == PhoneLoginPage.routeName) {
          LogUtil.v('当前页面为：$routeSettingName,停止跳转');
          return;
        }

        Timer(Duration(seconds: 2), () {
          RongUtil.disconnect();
          RouteUtil.onVerifyLogin();
          GlobalEventBus().bus.fire(UserLoginEvent(false));
        });
      }
    }
  }

  static void dioOptionsConfig(Dio _dio, {int timeout = 99999}) {
    int x = 1000;
    _dio.options.receiveTimeout = timeout * x;
    _dio.options.connectTimeout = timeout * x;
    _dio.options.sendTimeout = timeout * x;
    _dio.options.contentType = Headers.jsonContentType;
  }

  static void dioInterceptors(Dio _dio) {
    if (!EnvConfig.isProd() || kDebugMode) {
      _dio.interceptors.add(
        LogInterceptor(
            requestBody: true,
            responseBody: true,
            logPrint: (v) {
              LogUtil.v(v);
            }),
      );
      _dio.interceptors.add(DioLogInterceptor());
    }

    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (options, handler) {
          options.baseUrl = HttpUtil.getServerPath() + "/api/v1";
          return handler.next(options);
        },
        onResponse: (response, handler) {
          String xRuntimeHeader = response.headers['x-runtime']?[0] ?? "";
          LogUtil.v("接口响应时间:$xRuntimeHeader");
          return handler.next(response);
        },
        onError: (DioError e, handler) {
          return handler.next(e);
        },
      ),
    );

    _dio.interceptors.add(
      InterceptorsWrapper(
        onResponse: (response, handler) {
          return handler.next(response);
        },
      ),
    );
  }

  ///通用请求
  static Future<Response> commonRequest(BuildContext context, String url,
      {bool isLoading = true,
      bool isErrorToast = true,
      String method = 'GET',
      Map<String, dynamic>? queryParameters,
      dynamic data,
      bool isCatchErrorLogin = true,
      CancelToken? cancelToken,
      int timeout: 60,
      String loadingText = "加载中..."}) async {
    if (isLoading) {
      EasyLoading.show(status: loadingText);
    }

    String requestUrl = '';

    if (url.startsWith('http')) {
      requestUrl = url;
    } else {
      requestUrl = getServerPath() + url;
    }

    Dio _dio = Dio();
    _dio.options.headers = {};
    _dio.options.method = method;
    HttpUtil.getRequestParams(
      _dio.options,
      method: method,
      url: url,
      queryParameters: queryParameters,
      data: data,
    );

    HttpUtil.dioOptionsConfig(_dio, timeout: timeout);
    HttpUtil.dioInterceptors(_dio);

    Future<Response> result = _dio
        .request(
      requestUrl,
      data: data,
      queryParameters: queryParameters,
      cancelToken: cancelToken ?? CancelToken(),
    )
        .catchError((error) {
      HttpUtil.dioErrorHandle(
        context,
        error,
        isErrorToast,
        isCatchErrorLogin: isCatchErrorLogin,
      );
    }).whenComplete(() {
      if (isLoading) {
        EasyLoading.dismiss();
      }
    });
    return result;
  }

  ///  下载文件
  static Future<Response> downloadFile(String url, String savePath, Map param,
      {String method = MethodGet,
      Map<String, dynamic>? headers,
      ProgressCallback? progressCallback}) async {
    Dio dio = Dio();

    Options options = Options();
    options.sendTimeout = 15000;
    options.receiveTimeout = 15000;
    options.method = method;

    if (headers != null) {
      options.headers = headers;
    }

    LogUtil.v("下载请求的url ：$url . 提交参数 param : $param , 请求头headers: $headers");

    return await dio.download(url, savePath,
        data: param, options: options, onReceiveProgress: progressCallback);
  }
}
